# -*- coding: utf-8 -*-
"""
Created on Wed Nov 26 18:05:08 2014
@chapter: 2.1.3
@name: 区间二分法
@author: revol
"""
from solve import Solve
# import math

class Dichotomy(Solve):
    def __init__(self,data=[]):
        Solve.__init__(self,data)
        if data:
            self.calc(data)
        self._name=u"二分法"
        self._description=u"二分法的基本思路是通过计算隔根区间的中点，\n\
逐步将隔根区间缩小，从而可得方程的近似根数列.\n本算法内建函数: f(x)=x^3-2x-5"
        self._paramenters=[{'name':'left','type':self.typeFLOAT},
                           {'name':'right','type':self.typeFLOAT},
                           {'name':'accuracy','type':self.typeFLOAT}]
        
    def f(self,x):
        return x**3-2*x-5
    
    def calc(self, data):
        Solve.calc(self, data)
        low=self._data['left']
        high=self._data['right']
        accuracy=self._data['accuracy']
        self._result=self._dichotomy(low, high,accuracy,self.f)
        return self._result
        
#     def _dichotomy(self,low,high,accuracy,f):
#递归版本，不知为什么没有返回值
#         m=(low+high)/2
#         if f(low) ==0:return low
#         if f(high)==0:return high
#         if abs(low-high)<=accuracy:
#             return m
#         if f(low)*f(m)<=0:
#             self._dichotomy(low,m,accuracy,f)
#         else:
#             self._dichotomy(m,high,accuracy,f)       
     
     
    def _dichotomy(self,low,high,accuracy,f):
    #迭代版本，用递归装逼失败
        if f(low) ==0:return low
        if f(high)==0:return high
        while(abs(high-low)>accuracy):
            m=(low+high)/2
            if f(low)*f(m)<=0:
                high=m
            else:
                low=m
        return (low+high)/2
        
    def getOutput(self):
        out=u"""参数
    左区间： %f
    右区间： %f
    精度： %f
近似根： %f \n""" %(self._data['left'],self._data['right'],self._data['accuracy'],self._result)
        return out
    
if __name__ == '__main__':
    data={'left':1.0,'right':5.0,'accuracy':0.000005}
    test=Dichotomy(data)
    print test.getOutput()
    print("更换函数为x^2-2x+1")
    test.f=lambda x:x**2-2*x+1
    test.calc(data)
    print test.getOutput()
    print test.getResult()
    print test.getDescription()
    print test.getParamenters()
          
        